#include "../../server/BindingManager.hpp"
#include <gtest/gtest.h>
#include <unordered_map>
#include <string>

micromq::BindingManager::ptr manager;

class BindingTest : public testing::Environment
{
public:
    virtual void SetUp() override
    {
        manager = std::make_shared<micromq::BindingManager>("./meta.db");
    }

    virtual void TearDown() override
    {
        // manager->clear();
    }
};

TEST(binding_test, insert_test)
{
    manager->bind("e1", "q1", "news.music.#", true);
    manager->bind("e1", "q2", "news.sport.#", true);
    manager->bind("e2", "q1", "news.music.pop", true);
    manager->bind("e2", "q3", "news.sport.ball", true);

    manager->bind("e3", "q4", "news.sport.ball", true);
    manager->bind("e4", "q4", "news.sport.ball", true);
    manager->bind("e5", "q5", "news.sport.ball", true);
    ASSERT_EQ(manager->size(), 7);
}

TEST(binding_test, select_test)
{
    ASSERT_EQ(manager->isExists("e1", "q1"), true);
    ASSERT_EQ(manager->isExists("e1", "q2"), true);
    ASSERT_EQ(manager->isExists("e2", "q1"), true);
    ASSERT_EQ(manager->isExists("e2", "q3"), true);

    ASSERT_EQ(manager->isExists("e3", "q4"), true);
    ASSERT_EQ(manager->isExists("e4", "q4"), true);
    ASSERT_EQ(manager->isExists("e5", "q5"), true);

    micromq::BindingInfo bindingInfo = manager->getBindingInfoByEcxchange("e1");
    ASSERT_EQ(bindingInfo["q1"]->_exchangeName, std::string("e1"));
    ASSERT_EQ(bindingInfo["q1"]->_msgQueueName, std::string("q1"));
    ASSERT_EQ(bindingInfo["q1"]->_bindingKey, std::string("news.music.#"));

    micromq::Binding::ptr binding = manager->getBindingByEntry("e2", "q3");
    ASSERT_EQ(binding->_exchangeName, std::string("e2"));
    ASSERT_EQ(binding->_msgQueueName, std::string("q3"));
    ASSERT_EQ(binding->_bindingKey, std::string("news.sport.ball"));
}

TEST(binding_test, delete_test)
{
    manager->unbindByEntry("e1", "q2");
    manager->unbindByEcxchange("e2");
    manager->unbindByMsgQueue("q4");

    ASSERT_EQ(manager->isExists("e1", "q1"), true);
    ASSERT_EQ(manager->isExists("e1", "q2"), false);
    ASSERT_EQ(manager->isExists("e2", "q1"), false);
    ASSERT_EQ(manager->isExists("e2", "q3"), false);

    ASSERT_EQ(manager->isExists("e3", "q4"), false);
    ASSERT_EQ(manager->isExists("e4", "q4"), false);
    ASSERT_EQ(manager->isExists("e5", "q5"), true);
}

int main(int argc, char* argv[])
{
    testing::InitGoogleTest(&argc, argv);
    testing::AddGlobalTestEnvironment(new BindingTest);
    RUN_ALL_TESTS();

    return 0;
}